package jmetal.util.archive;

import hidra.jmetal.core.*;
import hidra.metaheuristics.mopsodfrv3.MOPSODFRV3;

import java.sql.Time;
import java.util.Comparator;
import java.util.Random;

import jmetal.util.comparators.*;
import jmetal.util.Distance;

public class DiversityFactorArchive extends Archive {

	private int maxSize_;

	/**
	 * stores the number of the objectives.
	 */
	private int objectives_;    

	/**
	 * Stores a <code>Comparator</code> for dominance checking.
	 */
	protected Comparator dominance_;

	/**
	 * Stores a <code>Comparator</code> for equality checking (in the objective
	 * space).
	 */
	protected Comparator equals_;

	/**
	 * Stores a <code>Comparator</code> for checking crowding distances.
	 */
	private Comparator diversityFactor_;

	private Comparator crowdingDistance_; 

	/**
	 * Stores a <code>Distance</code> object, for distances utilities
	 */
	private Distance distance_; 

	private int itAux;
	private int it;

	public DiversityFactorArchive(int maxSize, int objectivesNumber) {
		super(maxSize);
		maxSize_ = maxSize;
		objectives_ = objectivesNumber;
		dominance_ = new DominanceComparator();
		equals_ = new EqualSolutions();
		diversityFactor_ = new DiversityFactorComparator();
		crowdingDistance_ = new CrowdingComparator();

		distance_ = new Distance();
		itAux = 0;
		it = 0;
	}

	public boolean add(Solution solution){

		int flag = 0;
		int i = 0;
		Solution aux; //Store an solution temporally
		while (i < solutionsList_.size()){
			aux = solutionsList_.get(i);            

			flag = dominance_.compare(solution,aux);
			if (flag == 1) {               // The solution to add is dominated
				return false;                // Discard the new solution
			} else if (flag == -1) {       // A solution in the archive is dominated
				solutionsList_.remove(i);    // Remove it from the population            
			} else {
				if (equals_.compare(aux,solution)==0) { // There is an equal solution 
					// in the population
					return false; // Discard the new solution
				}  // if
				i++;
			}
		}
		// Insert the solution into the archive
		solutionsList_.add(solution);

		if (size() > maxSize_) { // The archive is full
			distance_.diversityFactorAssignment(this,objectives_);      
			remove(indexWorst(diversityFactor_)); 
		}
		
		return true;
	} // add

} // CrowdingArchive
